package com.xiaomaoguai.webkit.core.utils;

import java.lang.reflect.Array;

/**
 * @Description :
 * @FileName: XmgArrayUtils.java
 * @Author :WeiHui.Zhang
 * @Data : 2015年5月8日 下午4:36:57
 * @Version:V1.00
 */
public abstract class XmgArrayUtils extends org.apache.commons.lang3.ArrayUtils {

	/**
	 * An empty immutable <code>String</code> array.
	 */
	public static final String[] EMPTY_STRING_ARRAY = new String[0];

	/**
	 * Determine whether the given object is an array: either an Object array or
	 * a primitive array.
	 * 
	 * @param obj
	 *            the object to check
	 */
	public static boolean isArray(Object obj) {
		return (obj != null && obj.getClass().isArray());
	}

	/**
	 * To String，分割字符为<code>,</code>
	 * 
	 * @param array
	 *            目标数组
	 * @see {@link #toString(Object[], String)}
	 */
	public static String toString(Object[] array) {
		return toString(array, ",");
	}

	/**
	 * To String
	 * 
	 * @param array
	 *            目标数组
	 * @param separater
	 *            分割字符
	 */
	public static String toString(Object[] array, char separater) {
		return toString(array, "" + separater);
	}

	/**
	 * To String
	 * 
	 * @param array
	 *            目标数组
	 * @param separater
	 *            分割字符串
	 */
	public static String toString(Object[] array, String separater) {
		if (array == null || array.length == 0) {
			return "";
		}
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < array.length; i++) {
			result.append(array[i] != null ? array[i].toString() : "");
			if (i < array.length - 1) {
				result.append(separater);
			}
		}
		return result.toString();
	}

	/**
	 * 初始化一个数组
	 * 
	 * @param clazz
	 *            数组的类型
	 * @param length
	 *            数组的长度
	 * @return 泛型数组
	 */
	@SuppressWarnings("unchecked")
	public static <T> T[] newInstance(Class<T> clazz, int length) {
		return (T[]) Array.newInstance(clazz, length);
	}

	/**
	 * Append the given object to the given array, returning a new array
	 * consisting of the input array contents plus the given object.
	 * 
	 * @param array
	 *            the array to append to (can be <code>null</code>)
	 * @param obj
	 *            the object to append
	 * @return the new array (of the same component type; never
	 *         <code>null</code>)
	 */
	public static <A, O extends A> A[] addObjectToArray(A[] array, O obj) {
		Class<?> compType = Object.class;
		if (array != null) {
			compType = array.getClass().getComponentType();
		} else if (obj != null) {
			compType = obj.getClass();
		}
		int newArrLength = (array != null ? array.length + 1 : 1);
		@SuppressWarnings("unchecked")
		A[] newArr = (A[]) Array.newInstance(compType, newArrLength);
		if (array != null) {
			System.arraycopy(array, 0, newArr, 0, array.length);
		}
		newArr[newArr.length - 1] = obj;
		return newArr;
	}

	/**
	 * Convert the given array (which may be a primitive array) to an object
	 * array (if necessary of primitive wrapper objects).
	 * <p>
	 * A <code>null</code> source value will be converted to an empty Object
	 * array.
	 * 
	 * @param source
	 *            the (potentially primitive) array
	 * @return the corresponding object array (never <code>null</code>)
	 * @throws IllegalArgumentException
	 *             if the parameter is not an array
	 */
	public static Object[] toObjectArray(Object source) {
		if (source instanceof Object[]) {
			return (Object[]) source;
		}
		if (source == null) {
			return new Object[0];
		}
		if (!source.getClass().isArray()) {
			throw new IllegalArgumentException("Source is not an array: " + source);
		}
		int length = Array.getLength(source);
		if (length == 0) {
			return new Object[0];
		}
		Class<?> wrapperType = Array.get(source, 0).getClass();
		Object[] newArray = (Object[]) Array.newInstance(wrapperType, length);
		for (int i = 0; i < length; i++) {
			newArray[i] = Array.get(source, i);
		}
		return newArray;
	}

	/**
	 * <p>
	 * Produces a new <code>String</code> array containing the elements between
	 * the start and end indices.
	 * </p>
	 *
	 * <p>
	 * The start index is inclusive, the end index exclusive. Null array input
	 * produces null output.
	 * </p>
	 *
	 * @param array
	 *            the array
	 * @param startIndexInclusive
	 *            the starting index. Undervalue (&lt;0) is promoted to 0,
	 *            overvalue (&gt;array.length) results in an empty array.
	 * @param endIndexExclusive
	 *            elements up to endIndex-1 are present in the returned
	 *            subarray. Undervalue (&lt; startIndex) produces empty array,
	 *            overvalue (&gt;array.length) is demoted to array length.
	 * @return a new array containing the elements between the start and end
	 *         indices.
	 */
	public static String[] subarray(String[] array, int startIndexInclusive, int endIndexExclusive) {
		if (array == null) {
			return null;
		}
		if (startIndexInclusive < 0) {
			startIndexInclusive = 0;
		}
		if (endIndexExclusive > array.length) {
			endIndexExclusive = array.length;
		}
		int newSize = endIndexExclusive - startIndexInclusive;
		if (newSize <= 0) {
			return EMPTY_STRING_ARRAY;
		}

		String[] subarray = new String[newSize];
		System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
		return subarray;
	}

}
